#include "device_syms.h"
#include <sys/system_properties.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/utsname.h>

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

struct device_syms {
	char* device;
	char* build_id;
	void* address;
};

struct device_syms ptmx_fops_addresses[] = {
		{"C1505","11.3.A.0.47",(void*)0xc093ee30},
		{"C1505","11.3.A.2.13",(void*)0xc093ed70},
		{"C5302","12.0.A.1.284",(void*)0xc0e3bed8},
		{"C5303","12.0.A.1.284",(void*)0xc0e3bed8},
		{"C5306","12.0.A.1.284",(void*)0xc0e3bed8},
		{"C5306","12.0.A.1.257",(void*)0xc0e3b890},
		{"C5303","12.0.A.1.257",(void*)0xc0e3b890},
		{"C5302","12.0.A.1.257",(void*)0xc0e3b890},
		{"C5306","12.0.A.1.211",(void*)0xc0e3b8d0},
		{"C5303","12.0.A.1.211",(void*)0xc0e3b8d0},
		{"C5302","12.0.A.1.211",(void*)0xc0e3b8d0},
		{"M35h","2.0.A.1.257",(void*)0xc0e3b890},
		{"C2104","15.0.A.1.31",(void*)0xc0f02640},
		{"C2105","15.0.A.1.31",(void*)0xc0f02640},
		{"C2104","15.0.A.1.36",(void*)0xc0f02640},
		{"C2105","15.0.A.1.36",(void*)0xc0f02640},
		{"C6616","10.1.1.A.1.319",(void*)0xc0d37488},
		{"C6606","10.1.1.B.0.166",(void*)0xc0d37488},
		{"C6603","10.3.A.0.423",(void*)0xc0e46fd0},
		{"C6602","10.3.A.0.423",(void*)0xc0e46fd0},
		{"C6603","10.1.1.A.1.307",(void*)0xc0d37488},
		{"C6602","10.1.1.A.1.307",(void*)0xc0d37488},
		{"C6603","10.1.1.A.1.253",(void*)0xc0d37488},
		{"C6602","10.1.1.A.1.253",(void*)0xc0d37488},
		{"C6503","10.3.A.0.423",(void*)0xc0e46ce0},
		{"C6502","10.3.A.0.423",(void*)0xc0e46ce0},
		{"C6506","10.3.A.0.423",(void*)0xc0e46ce0},
		{"F-02E","V16R46A",(void*)0xc0ca1ca8},
		{"F-02E","V17R48A",(void*)0xc0ca1ca8},
		{"F-02E","V19R50D",(void*)0xc0ca1d28},
		{"F-04E","V08R39A",(void*)0xc0b955f4},
		{"F-05D","V08R31C",(void*)0xc07bc164},
		{"F-05D","V11R40A",(void*)0xc07bbf44},
		{"F-06E","V21R48D",(void*)0xc10d7774},
		{"F-07E","V19R38A",(void*)0xc10d75b4},
		{"F-07E","V20R39D",(void*)0xc10d7634},
		{"F-07E","V21R40B",(void*)0xc10d7634},
		{"F-10D","V10R42A",(void*)0xc0b7755c},
		{"F-10D","V21R48A",(void*)0xc09a60e0},
		{"F-10D","V22R49C",(void*)0xc09a60bc},
		{"F-11D","V24R40A",(void*)0xc1056998},
		{"FJL21","V23R39X",(void*)0xc0ee31f8},
		{"FJL21","V37R47A",(void*)0xc0ee3378},
		{"FJL21","V39R48C",(void*)0xc0ee3378},
		{"HTC6600LVW","JSS15J",(void*)0xc0f1d834},
		{"HTL21","JRO03C",(void*)0xc0d1d944},
		{"HTL21","JRO03C",(void*)0xc0d1dec4},
		{"HTL21","JRO03C",(void*)0xc0d1df44},
		{"HTL22","JZO54K",(void*)0xc0df467c},
		{"HTL22","JZO54K",(void*)0xc0df52bc},
		{"HTL22","JDQ39",(void*)0xc0ef7d44},
		{"HTL22","JDQ39",(void*)0xc0efc244},
		{"HTX21","JRO03C",(void*)0xc0ccc0b4},
		{"HTX21","JRO03C",(void*)0xc0ccc134},
		{"IS12S","6.1.D.1.91",(void*)0xc0c9b7c0},
		{"IS12S","6.1.D.1.103",(void*)0xc0c9b7c0},
		{"IS15SH","01.00.04",(void*)0xc0edaf90},
		{"IS17SH","01.00.04",(void*)0xc0edae90},
		{"ISW11F","FIK700",(void*)0xc080e268},
		{"ISW11F","FIK700",(void*)0xc080e028},
		{"URBANO PROGRESSO","010.0.3000",(void*)0xc0dc0a10},
		{"URBANO PROGRESSO","011.0.3100",(void*)0xc0dc0a10},
		{"ISW13F","V69R51I",(void*)0xc09fc600},
		{"ISW13F","V75R58A",(void*)0xc09fa200},
		{"ISW13HT","IMM76D",(void*)0xc127a8b0},
		{"L-01E","IMM76L",(void*)0xc0e715c8},
		{"L-01F","JDQ39B",(void*)0xc101c490},
		{"L-01E","JZO54K",(void*)0xc0fac580},
		{"L-02E","JZO54K",(void*)0xc0d926e0},
		{"L-05D","JZO54K",(void*)0xc0d885a8},
		{"LG-E975","JZO54K",(void*)0xc0f9da70},
		{"LT28h","6.2.B.0.211",(void*)0xc117e328},
		{"LT28i","6.2.B.0.211",(void*)0xc117e328},
		{"LT26i","6.2.B.0.200",(void*)0xc0cc37e8},
		{"LT26i","6.2.B.0.211",(void*)0xc0cc37e8},
		{"LT26i","6.2.B.1.96",(void*)0xc0cc3788},
		{"LT26ii","6.2.B.0.200",(void*)0xc0cc37e8},
		{"LT26ii","6.2.B.0.211",(void*)0xc0cc37e8},
		{"LT26w","6.2.B.0.200",(void*)0xc0cc3dc0},
		{"LT26w","6.2.B.0.211",(void*)0xc0cc3dc0},
		{"LT22i","6.2.A.1.100",(void*)0xc09dbed8},
		{"P-02E","10.0657",(void*)0xc0f72ba4},
		{"P-02E","10.0659",(void*)0xc0f72ba4},
		{"P-02E","10.0691",(void*)0xc0f72ba4},
		{"P-02E","10.0733",(void*)0xc0f72ba4},
		{"P-02E","10.0767",(void*)0xc0f72be4},
		{"P-02E","10.0798",(void*)0xc0f72ba4},
		{"ST23i","11.0.A.5.5",(void*)0xc095a46c},
		{"ST23i","11.0.A.5.8",(void*)0xc095846c},
		{"ST27i","6.2.A.1.100",(void*)0xc09b98e0},
		{"ST27a","6.2.A.1.100",(void*)0xc09b98e0},
		{"ST26i","11.2.A.0.21",(void*)0xc09b36dc},
		{"ST26a","11.2.A.0.21",(void*)0xc09b36dc},
		{"ST26i","11.2.A.0.31",(void*)0xc098365c},
		{"ST26a","11.2.A.0.31",(void*)0xc098365c},
		{"N-03E","A7000241",(void*)0xc0f702fc},
		{"N-03E","A7001821",(void*)0xc0f702fc},
		{"N-03E","A7002001",(void*)0xc0f702fc},
		{"N-03E","A7202001",(void*)0xc0f94d94},
		{"N-03E","A7202201",(void*)0xc0f94d94},
		{"N05E","A1000311",(void*)0xc0f58700},
		{"SC-01E","IMM76D.SC01EOMALJ3",(void*)0xc10a5a48},
		{"SC-01E","IMM76D.SC01EOMAMF2",(void*)0xc10a5a48},
		{"SC-04E","JDQ39.SC04EOMUAMDI",(void*)0xc1169808},
		{"SC-04E","JDQ39.SC04EOMUAMF1",(void*)0xc1169848},
		{"SC-04E","JDQ39.SC04EOMUAMF2",(void*)0xc1169848},
		{"SC-04E","JDQ39.SC04EOMUAMG2",(void*)0xc1169848},
		{"SCL21","IMM76D.SCL21KDALJD",(void*)0xc0c71dc0},
		{"SGP321","10.1.1.A.1.307",(void*)0xc0d36740},
		{"SGP312","10.1.C.0.370",(void*)0xc0d35ca8},
		{"SGP311","10.1.C.0.370",(void*)0xc0d35ca8},
		{"LT30p","9.1.A.1.141",(void*)0xc0d02b00},
		{"LT30p","9.1.A.1.142",(void*)0xc0d02b00},
		{"LT30p","9.1.A.1.145",(void*)0xc0d02b00},
		{"LT29i","9.1.B.0.411",(void*)0xc0d01f60},
		{"LT29i","9.1.B.1.67",(void*)0xc0d01f60},
		{"LT25i","9.1.A.1.140",(void*)0xc0d032f8},
		{"LT25i","9.1.A.1.142",(void*)0xc0d032b8},
		{"LT25i","9.1.A.1.145",(void*)0xc0d032b8},
		{"SBM203SH","S0024",(void*)0xc0ef6580},
		{"SH-02E","02.00.03",(void*)0xc0ef62c0},
		{"SH-04E","01.00.02",(void*)0xc0eed190},
		{"SH-04E","01.00.03",(void*)0xc0eed190},
		{"SH-04E","01.00.04",(void*)0xc0eed150},
		{"SH-05E","01.00.05",(void*)0xc0d95870},
		{"SH-05E","01.00.06",(void*)0xc0d95870},
		{"SH-06E","01.00.01",(void*)0xc104e6c8},
		{"SH-06E","01.00.05",(void*)0xc104f1c8},
		{"SH-06E","01.00.06",(void*)0xc1050090},
		{"SH-06E","01.00.07",(void*)0xc1050090},
		{"SH-07E","01.00.03",(void*)0xc0f33508},
		{"SH-09D","02.00.03",(void*)0xc0dd5e58},
		{"SHL21","01.00.09",(void*)0xc0fe01b0},
		{"SHL21","01.01.02",(void*)0xc0dd8810},
		{"SO-01E","9.1.C.0.473",(void*)0xc0d03208},
		{"SO-01E","9.1.C.1.103",(void*)0xc0d03288},
		{"SO-02E","10.1.D.0.343",(void*)0xc0e38620},
		{"SO-03E","10.1.E.0.265",(void*)0xc0d36aa8},
		{"SO-03E","10.1.E.0.269",(void*)0xc0d36aa8},
		{"SO-04D","7.0.D.1.137",(void*)0xc0c9d8a0},
		{"SO-04D","9.1.C.0.475",(void*)0xc0d024a0},
		{"SO-04D","9.1.C.1.103",(void*)0xc0d024a0},
		{"SO-04E","10.1.1.D.0.179",(void*)0xc0f392d8},
		{"SO-04E","10.1.1.D.2.26",(void*)0xc0f392d8},
		{"SO-05D","9.1.C.0.475",(void*)0xc0d01e50},
		{"SO-05D","9.1.C.1.103",(void*)0xc0d01e90},
		{"SOL21","9.0.F.0.226",(void*)0xc0cffe78},
		{"SOL21","9.1.D.0.395",(void*)0xc0d030c8},
		{"SOL21","9.1.D.0.401",(void*)0xc0d030c8},
		{"SOL22","10.2.F.3.43",(void*)0xc0e389b0},
		{"SOL22","10.2.F.3.81",(void*)0xc0e389b0},
		{"Sony Tablet P","TISU0144",(void*)0xc06e6da0},
		{"Sony Tablet S","TISU0143",(void*)0xc06e4d18},
		{"T-02D","V10R36A",(void*)0xc121b61c},
		{"Nexus 4","JDQ39",(void*)0xc0ef72f0},
		{"Galaxy Nexus","JOP40C",(void*)0xc08b5344},
		{"NEC-101T","112.55.12.2.02.01",(void*)0xc02c6da8},
		{"Galaxy Nexus","JZO54K",(void*)0xc08b3224},
		{"C5503","10.1.1.A.1.310",(void*)0xc0d37a98},
		{"C5502","10.1.1.A.1.310",(void*)0xc0d37a98},
		{"M36h","10.1.1.A.1.310",(void*)0xc0d37a98},
		{"ASUS Pad TF300T","JRO03C.JP_epad-10.4.2.20-20121228",(void*)0xc0a706d8},
		{"SCH-I545","JDQ39.I545VRUAME7",(void*)0xc1067b48},
		{"HTL21","JRO03C",(void*)0xc0d1df44},
		{"L-01F","JDQ39B",(void*)0xc101c4d0},
		{"LGL22","JDQ39B",(void*)0xc101a7a0},
		{"LGL22","JDQ39B",(void*)0xc101a7a0},
		{"LGL23","JDQ39B",(void*)0xc111fba0},
		{"GT-I9195","JDQ39.I9195XXUAMF5",(void*)0xc0f26100},
		{"GT-I9300","GarTot-HK-4.1.2-ZSEMI1-I9300",(void*)0xc0ab0c40},
		{"201K","117.1.1c00",(void*)0xc0f17a60},
		{"P-03E","10.1010",(void*)0xc11b3574},
		{"P-02E","10.0818",(void*)0xc0f72ba4},
		{"202K","101.0.2c10",(void*)0xc0f469f8},
		{"SH-01E","02.00.02",(void*)0xc0dd44f0},
		{"Nexus 5","KTU84P",(void*)0xc1235dd0},
		{"LGL22","KOT49I",(void*)0xc12532a0},
};

struct device_syms sys_call_table_addresses[] = {
		//{"MI-ONE Plus","3.4.0-perf-g1ccebb5-00107-g6c5aa70",(void*)0xc000e5a8},
};

void* device_syms_get(const char* name) {
	char device[PROP_VALUE_MAX] = {0};
	int i = 0;
	struct device_syms* start = NULL;
	int len = 0;
	struct utsname info = {0};
	if (uname(&info) != 0) {
		return NULL;
	}
	__system_property_get("ro.product.model", device);
	if (strcmp("sys_call_table", name) == 0){
		start = sys_call_table_addresses;
		len = arraysize(sys_call_table_addresses);
	} else {
		return NULL;
	}
	for (i=0; i<len; ++i) {
		if (strcmp(device, start[i].device) == 0 &&
		  strncmp(info.release, start[i].build_id, strlen(start[i].build_id)) == 0) {
			return start[i].address;
		}
	}

	return NULL;
}
